// reads a byte from the specified port
unsigned char port_byte_in(unsigned short port) {
	unsigned char result;
	// '"=a" (result)' means put the contents of the al register into result when done
	// '"d" (port)' means load edx with the value of port
	__asm__("in %%dx, %%al" : "=a" (result) : "d" (port));
	return result;
}

void port_byte_out(unsigned short port, unsigned char data) {
	// '"a" (data)' means load eax with data
	// '"d" (port)' means load edx with port
	__asm__("out %%al, %%dx" : : "a" (data), "d" (port));
}

unsigned short port_word_in(unsigned short port) {
	unsigned short result;
	__asm__("in %%dx, %%ax" : "=a" (result) : "d" (port));
	return result;
}

void port_word_out(unsigned short port, unsigned short data) {
	__asm__("out %%ax, %%dx" : : "a" (data), "d" (port));
}
